﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using OpenXmlPowerTools;

namespace Songhay.OpenXml
{
    using Songhay.OpenXml.Models;

    /// <summary>
    /// Static members for Open XML.
    /// </summary>
    public static partial class OpenXmlUtility
    {
        /// <summary>
        /// Transforms the OPC Document to HTML.
        /// </summary>
        /// <param name="wordDoc">The OPC Document.</param>
        /// <param name="htmlConverterSettings">The HTML converter settings.</param>
        /// <remarks>
        /// This member duplicates <see cref="OpenXmlPowerTools.HtmlConverter.ConvertToHtml"/>
        /// to allow modifications elsewhere.
        /// </remarks>
        public static XElement TransformOpcToHtml(WordprocessingDocument wordDoc, SonghayHtmlConverterSettings htmlConverterSettings)
        {
            return TransformOpcToHtml(wordDoc, htmlConverterSettings, null);
        }

        /// <summary>
        /// Transforms the OPC Document to HTML.
        /// </summary>
        /// <param name="wordDoc">The OPC Document.</param>
        /// <param name="htmlConverterSettings">The HTML converter settings.</param>
        /// <param name="imageHandler">The image handler.</param>
        /// <remarks>
        /// This member duplicates <see cref="OpenXmlPowerTools.HtmlConverter.ConvertToHtml"/>
        /// to allow modifications elsewhere.
        /// </remarks>
        public static XElement TransformOpcToHtml(WordprocessingDocument wordDoc, SonghayHtmlConverterSettings htmlConverterSettings, Func<ImageInfo, XElement> imageHandler)
        {
            InitEntityMap();

            if(htmlConverterSettings.ConvertFormatting)
            {
                throw new InvalidSettingsException("Conversion with formatting is not supported");
            }

            RevisionAccepter.AcceptRevisions(wordDoc);
            var settings = new SimplifyMarkupSettings
            {
                RemoveComments = true,
                RemoveContentControls = true,
                RemoveEndAndFootNotes = true,
                RemoveFieldCodes = false,
                RemoveLastRenderedPageBreak = true,
                RemovePermissions = true,
                RemoveProof = true,
                RemoveRsidInfo = true,
                RemoveSmartTags = true,
                RemoveSoftHyphens = true,
                ReplaceTabsWithSpaces = true,
            };
            MarkupSimplifier.SimplifyMarkup(wordDoc, settings);
            XElement rootElement = wordDoc.MainDocumentPart.GetXDocument().Root;
            AnnotateHyperlinkContent(rootElement);
            var xhtml = (XElement)TransformPackageNode(wordDoc, htmlConverterSettings, rootElement, imageHandler);

            // Note: the xhtml returned by TransformPackage contains objects of type
            // XEntity.  PtOpenXmlUtil.cs define the XEntity class.  See
            // http://blogs.msdn.com/ericwhite/archive/2010/01/21/writing-entity-references-using-linq-to-xml.aspx
            // for detailed explanation.
            //
            // If you further transform the XML tree returned by TransformPackage, you
            // must do it correctly, or entities will not be serialized properly.

            return xhtml;
        }

        public class InvalidSettingsException : Exception
        {
            public InvalidSettingsException(string message) : base(message) { }
        }

        private enum AnnotateState
        {
            NotInHyperlink,
            InFirstSection,
            InSecondSection,
        }

        static Dictionary<char, string> EntityMap = null;

    }
}
